<template>
  <div class="chat-container">
    <div class="chat-header">
      <h3>{{ title }}</h3>
    </div>
    <div class="chat-messages" ref="messagesContainer">
      <div v-for="(message, index) in messages" :key="index" class="message-item" :class="message.type">
        <div class="message-content">
          <template v-if="message.type === 'system'">
            <div v-if="typeof welcomeMessage === 'function'">
              <component :is="welcomeMessage" />
            </div>
            <div v-else>
              {{ welcomeMessage }}
            </div>
          </template>
          <template v-else-if="message.type === 'user'">
            <div v-if="typeof renderUserMessage === 'function'">
              <component :is="renderUserMessage(message.content)" />
            </div>
            <div v-else>
              {{ message.content }}
            </div>
          </template>
          <template v-else-if="message.type === 'assistant'">
            <div v-if="typeof renderAssistantMessage === 'function'">
              <component :is="renderAssistantMessage(message.content)" />
            </div>
            <div v-else class="markdown-content" v-html="parseMarkdown(message.content)"></div>
          </template>
        </div>
      </div>
      <div v-if="thinking" class="message-item assistant">
        <div class="message-content">
          <span class="thinking-dots">
            <span class="dot">.</span>
            <span class="dot">.</span>
            <span class="dot">.</span>
          </span>
        </div>
      </div>
    </div>
    <div class="chat-input">
      <el-input
        v-model="inputMessage"
        type="textarea"
        :rows="3"
        placeholder="请输入消息..."
        @keyup.enter="handleSendMessage"
      />
      <el-button type="primary" @click="handleSendMessage" :loading="loading">
        发送
      </el-button>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, onMounted, nextTick, watch } from 'vue';
import { ElMessage } from 'element-plus';
import { Loading } from '@element-plus/icons-vue';
import { generateAI } from '@/apis/model';
import { marked } from 'marked';
import hljs from 'highlight.js';
import 'highlight.js/styles/github.css';

// 配置 marked
marked.setOptions({
  renderer: new marked.Renderer(),
  // highlight: function(code, lang) {
  //   const language = hljs.getLanguage(lang) ? lang : 'plaintext';
  //   return hljs.highlight(code, { language }).value;
  // },
  // langPrefix: 'hljs language-',
  pedantic: false,
  gfm: true,
  breaks: false,
  // sanitize: false,
  // smartLists: true,
  // smartypants: false,
  // xhtml: false
});

export interface Message {
  type: 'user' | 'assistant' | 'system';
  content: string;
}

export interface ChatProps {
  title?: string;
  agentId?: string;
  welcomeMessage?: string | (() => any);
  renderUserMessage?: (content: string) => any;
  renderAssistantMessage?: (content: string) => any;
  onMessageReceived?: (message: string) => void;
}

export default defineComponent({
  name: 'ChatComponent',
  components: {
    Loading,
  },
  props: {
    title: {
      type: String,
      default: '智能对话',
    },
    agentId: {
      type: String,
      default: '',
    },
    welcomeMessage: {
      type: [String, Function],
      default: '你好！我是AI助手，有什么可以帮你的吗？',
    },
    renderUserMessage: {
      type: Function,
      default: null,
    },
    renderAssistantMessage: {
      type: Function,
      default: null,
    },
    onMessageReceived: {
      type: Function,
      default: null,
    },
  },
  setup(props: ChatProps) {
    const messages = ref<Message[]>([]);
    const inputMessage = ref('');
    const loading = ref(false);
    const thinking = ref(false);
    const messagesContainer = ref<HTMLElement | null>(null);

    // 解析 markdown
    const parseMarkdown = (content: string) => {
      return marked(content);
    };

    // 添加欢迎消息
    onMounted(() => {
      messages.value.push({
        type: 'system',
        content: '',
      });
    });

    // 监听消息变化，自动滚动到底部
    watch(messages, async () => {
      await nextTick();
      if (messagesContainer.value) {
        messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
      }
    }, { deep: true });

    const handleSendMessage = async () => {
      if (!inputMessage.value.trim()) {
        ElMessage.warning('请输入消息内容');
        return;
      }

      const userMessage = inputMessage.value.trim();
      messages.value.push({
        type: 'user',
        content: userMessage,
      });

      inputMessage.value = '';
      loading.value = true;
      thinking.value = true;

      try {
        // 调用 generateAI 方法
        const response = await generateAI({
          mark: 'myDeepseek',
          message: userMessage,
        });

        // 如果有消息接收钩子，先调用钩子
        if (props.onMessageReceived) {
          props.onMessageReceived(response.data);
        }

        // 添加助手回复到消息列表
        messages.value.push({
          type: 'assistant',
          content: response.data,
        });
      } catch (error) {
        ElMessage.error('发送消息失败');
        console.error('发送消息失败:', error);
      } finally {
        loading.value = false;
        thinking.value = false;
      }
    };

    return {
      messages,
      inputMessage,
      loading,
      thinking,
      messagesContainer,
      handleSendMessage,
      parseMarkdown,
    };
  },
});
</script>

<style lang="scss" scoped>
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);

  .chat-header {
    padding: 15px;
    border-bottom: 1px solid #ebeef5;
    text-align: center;

    h3 {
      margin: 0;
      font-size: 16px;
      color: #303133;
    }
  }

  .chat-messages {
    flex: 1;
    padding: 20px;
    overflow-y: auto;
    background-color: #f5f7fa;

    .message-item {
      margin-bottom: 20px;
      display: flex;
      flex-direction: column;

      &.user {
        align-items: flex-end;
      }

      &.assistant {
        align-items: flex-start;
      }

      .message-content {
        max-width: 80%;
        padding: 10px 15px;
        border-radius: 4px;
        word-break: break-word;

        .is-loading {
          margin-right: 5px;
        }

        :deep(.markdown-content) {
          h1, h2, h3, h4, h5, h6 {
            margin-top: 1em;
            margin-bottom: 0.5em;
            font-weight: bold;
          }

          p {
            margin: 0.5em 0;
          }

          ul, ol {
            padding-left: 2em;
            margin: 0.5em 0;
          }

          code {
            background-color: #f5f7fa;
            padding: 0.2em 0.4em;
            border-radius: 3px;
            font-family: monospace;
          }

          pre {
            background-color: #f5f7fa;
            padding: 1em;
            border-radius: 4px;
            overflow-x: auto;
            margin: 0.5em 0;

            code {
              background-color: transparent;
              padding: 0;
            }
          }

          blockquote {
            border-left: 4px solid #dcdfe6;
            padding-left: 1em;
            margin: 0.5em 0;
            color: #606266;
          }

          table {
            border-collapse: collapse;
            width: 100%;
            margin: 0.5em 0;

            th, td {
              border: 1px solid #dcdfe6;
              padding: 0.5em;
            }

            th {
              background-color: #f5f7fa;
            }
          }
        }
      }

      &.user .message-content {
        background-color: #409eff;
        color: #fff;
      }

      &.assistant .message-content {
        background-color: #fff;
        color: #303133;
        border: 1px solid #dcdfe6;
      }
    }
  }

  .chat-input {
    padding: 15px;
    border-top: 1px solid #ebeef5;
    display: flex;
    gap: 10px;

    .el-input {
      flex: 1;
    }
  }
}

.thinking-dots {
  display: inline-block;
  .dot {
    display: inline-block;
    animation: dotAnimation 1.4s infinite;
    opacity: 0;
    
    &:nth-child(1) {
      animation-delay: 0s;
    }
    
    &:nth-child(2) {
      animation-delay: 0.2s;
    }
    
    &:nth-child(3) {
      animation-delay: 0.4s;
    }
  }
}

@keyframes dotAnimation {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}
</style>
